﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Controls.Maps.Core;
using Microsoft.Phone.Controls.Maps;
using Microsoft.Phone.Controls.Maps.Platform;
using WP7Client.Managers;
using WP7Client.Helpers;
using MSH.Common.DAO;
using WP7Client.Controller;
using WP7Client.Classes;
using WP7Client.Resources;
using MSH.Common.Classes;

namespace WP7Client.UserInterface.Pages
{
    public enum InitMapMode
    {
        AllfriendsOnMap = 0,
        PeopleNearbyOnMap
    }

    public partial class MapPage : MSHPhoneApplicationPage
    {
        private MapLayer PinLayer = new MapLayer();
        private Pushpin UserPin = new Pushpin();

        private InitMapMode CurrentMode;
        private Boolean Initiated = false;

        public MapPage()
        {
            InitializeComponent();
            theMap.CredentialsProvider = new ApplicationIdCredentialsProvider(Configuration.MapCredentials);
        }
        
        private void MSHPhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            if (NavigationContext != null && NavigationContext.QueryString != null && NavigationContext.QueryString.ContainsKey("MapMode"))
            {
                String itemName = null;
                NavigationContext.QueryString.TryGetValue("MapMode", out itemName);
                if (!String.IsNullOrEmpty(itemName))
                {
                    switch (itemName)
                    {
                        case "AllFriends":
                            Init(InitMapMode.AllfriendsOnMap);
                            break;
                        case "PeopleNearby":
                            Init(InitMapMode.PeopleNearbyOnMap);
                            break;
                    }
                }
            }
        }
    
        private void ComboBoxModes_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (ComboBoxModes == null)
                return;

            ComboBoxItem item = (ComboBoxModes.SelectedItem as ComboBoxItem);
            if (item != null)
            {
                if (item.Name.Equals("ItemRoad"))
                    theMap.Mode = new RoadMode();
                else if (item.Name.Equals("ItemAerial"))
                    theMap.Mode = new AerialMode(true);
            }
        }

        private void Init(InitMapMode mode)
        {
            if (!Initiated)
            {
                theMap.Children.Add(PinLayer);
                SetLocationPinUser();
                CurrentMode = mode;

                switch (mode)
                {
                    case InitMapMode.AllfriendsOnMap:
                        SetLocationPinsAllFriends();
                        break;
                    case InitMapMode.PeopleNearbyOnMap:
                        SetLocationPinsPeopleNearby();
                        break;
                }
                Initiated = true;
            }
        }

        private void SetLocationPinUser()
        {
            if (LocationManager.CurrentLocationData != null)
            {
                PinLayer.Children.Add(UserPin);
                UserPin.Location = new Location();
                UserPin.Location.Latitude = LocationManager.CurrentLocationData.Latitude;
                UserPin.Location.Longitude = LocationManager.CurrentLocationData.Longitude;
                UserPin.Background = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0x00));
                UserPin.Foreground = new SolidColorBrush(Color.FromArgb(0xFF, 0x00, 0x00, 0x00));
                UserPin.Content = "Your position";
            }
        }

        private void SetLocationPinsAllFriends()
        {
            foreach (Friend friend in ControllerHelper.FriendController.Friends)
            {
                if (friend.Location != null)
                {
                    Pushpin pin = new Pushpin();
                    PinLayer.Children.Add(pin);
                    
                    PushPinData data = new PushPinData(new SolidColorBrush(Color.FromArgb(0xFF, 0x00, 0x00, 0xFF)),
                            new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF)), "", friend.Username, true);

                    if (!String.IsNullOrEmpty(friend.SurName) && !String.IsNullOrEmpty(friend.FirstName))
                        data.Content = friend.FirstName + " " + friend.SurName;
                    else
                        data.Content = friend.Username;

                    if (friend.profilePrivacy == PrivacyEnum.Private)
                        data.IsEnabled = false;

                    pin.DataContext = data;

                    pin.Template = (ControlTemplate)theMapPage.Resources["pushPinTemplate"];
                    pin.ApplyTemplate();

                    pin.Location = new Location();
                    pin.Location.Longitude = friend.Location.Longitude;
                    pin.Location.Latitude = friend.Location.Latitude;
                }
            }

            OptimizeMapView();
        }

        private void SetLocationPinsPeopleNearby()
        {
            MapVisibility mapVisibility = MapVisibility.FriendsAndStrangers;
            Object tempMapVisibility = IsolatedStorageHelper.GetData(UserHelper.Username + ".MapVisibility");
            if (tempMapVisibility != null)
            {
                mapVisibility = (MapVisibility)Enum.Parse(typeof(MapVisibility), tempMapVisibility.ToString(), true);
            }
            
            if (mapVisibility == MapVisibility.FriendsAndStrangers || mapVisibility == MapVisibility.StrangersOnly)
            {
                foreach (PersonNearby person in ControllerHelper.PeopleNearbyController.PeopleNearby)
                {
                    Pushpin pin = new Pushpin();
                    PinLayer.Children.Add(pin);

                    PushPinData data = new PushPinData(new SolidColorBrush(Color.FromArgb(0xFF, 0x00, 0x80, 0x00)),
                        new SolidColorBrush(Color.FromArgb(0xFF, 0x00, 0x00, 0x00)), "", person.Username, true);

                    if (!String.IsNullOrEmpty(person.SurName) && !String.IsNullOrEmpty(person.FirstName))
                        data.Content = person.FirstName + " " + person.SurName;
                    else
                        data.Content = person.Username;

                    if (person.profilePrivacy == PrivacyEnum.Private || person.profilePrivacy == PrivacyEnum.Friends)
                        data.IsEnabled = false;

                    pin.DataContext = data;

                    pin.Template = (ControlTemplate)theMapPage.Resources["pushPinTemplate"];
                    pin.ApplyTemplate();

                    pin.Location = new Location();
                    pin.Location.Longitude = person.Longitude;
                    pin.Location.Latitude = person.Latitude;
                }
            }

            if (mapVisibility == MapVisibility.FriendsAndStrangers || mapVisibility == MapVisibility.FriendsOnly)
            {
                foreach (PersonNearby friend in ControllerHelper.PeopleNearbyController.FriendsNearby)
                {
                    Pushpin pin = new Pushpin();
                    PinLayer.Children.Add(pin);
                    
                    PushPinData data = new PushPinData(new SolidColorBrush(Color.FromArgb(0xFF, 0x00, 0x00, 0xFF)),
                        new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF)), "", friend.Username, true);

                    if (!String.IsNullOrEmpty(friend.SurName) && !String.IsNullOrEmpty(friend.FirstName))
                        data.Content = friend.FirstName + " " + friend.SurName;
                    else
                        data.Content = friend.Username;

                    if (friend.profilePrivacy == PrivacyEnum.Private)
                        data.IsEnabled = false;

                    pin.DataContext = data;

                    pin.Template = (ControlTemplate)theMapPage.Resources["pushPinTemplate"];
                    pin.ApplyTemplate();

                    pin.Location = new Location();
                    pin.Location.Longitude = friend.Longitude;
                    pin.Location.Latitude = friend.Latitude;
                }
            }
            
            OptimizeMapView();
        }

        private void OptimizeMapView()
        {
            LocationRect zoom = null;

            if (CurrentMode == InitMapMode.AllfriendsOnMap || LocationManager.CurrentLocationData == null)
            {
                Location averageLocation = new Location();
                double Count = 0;
                double SumLatitude = 0;
                double SumLongitude = 0;

                foreach (UIElement element in PinLayer.Children)
                {
                    if (element is Pushpin)
                    {
                        Pushpin pin = (Pushpin)element;
                        SumLatitude += pin.Location.Latitude;
                        SumLongitude += pin.Location.Longitude;
                        Count++;
                    }
                }

                averageLocation.Latitude = SumLatitude / Count;
                averageLocation.Longitude = SumLongitude / Count;

                theMap.Center = theMap.Center = averageLocation;
            }
            else
                theMap.Center = UserPin.Location;

            try
            {
                zoom = new LocationRect(
                    PinLayer.Children.Max((p) => (p as Pushpin).Location.Latitude),
                    PinLayer.Children.Min((p) => (p as Pushpin).Location.Longitude),
                    PinLayer.Children.Min((p) => (p as Pushpin).Location.Latitude),
                    PinLayer.Children.Max((p) => (p as Pushpin).Location.Longitude));
            }
            catch (Exception e) { theMap.ZoomLevel = 0; }

            if(zoom != null)
                theMap.SetView(zoom);
        }

        private void Refresh()
        {
            if (theMap.Children.Contains(PinLayer))
                theMap.Children.Remove(PinLayer);
            if (PinLayer.Children.Contains(UserPin))
                PinLayer.Children.Remove(UserPin);

            PinLayer = new MapLayer();
            UserPin = new Pushpin();

            Initiated = false;
            Init(CurrentMode);    
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Refresh();
        }

        private void buttonPin_Click(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;
            PushPinData data = null;
            if (button != null && button.DataContext != null && button.DataContext is PushPinData)
            {
                data = button.DataContext as PushPinData;
                if(data.IsEnabled)
                    NavigationHelper.NavigateTo(String.Format("/UserInterface/Pages/ProfilePage.xaml?username={0}", data.Username));
            }
        }

       
    }
}